home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 1 / LSD Compendium Deluxe 1.iso / a / programming / assembly / eurostars2.0.lha / ES.asm next >
Encoding:
Assembly Source File  |  1992-10-18  |  45.7 KB  |  1,807 lines

  1. *\  :ts=8 bk=0
  2. *
  3. * ES.asm:    A neato star program based on some Euro code (from the group
  4. *        "Absence" I believe).
  5. *
  6. *        This code came from Portal under the name STARTOY.LZH and
  7. *        was uploaded by Greg Cunningham (author of BaudBandit).
  8. *        The program was disassembled using ReSource 4.16 (from The
  9. *        Puzzle Factory), and modified from there by me.
  10. *
  11. *        v2.0 Improvements:
  12. *        o Now compatible with the A4000, AA chipset, and v3.0.
  13. *        o Menu button no longer lunches screen.
  14. *        o Completely new point transformation code.
  15. *        o New star rendering code.
  16. *        o Code speed MEGA-improved over European original
  17. *          (so there, nyah, pthbthbpttt!! :-) :-) :-) :-) ).
  18. *        o Much better performance on a plain 68000-based system.
  19. *        o Sine table resolution increased, yielding finer rotation.
  20. *        o Odd angles now supported.
  21. *        o Smarter about overscan.
  22. *        o Parses Workbench ToolTypes.
  23. *
  24. *        v1.0 Improvements:
  25. *        o No longer Disable()s the world whle running.
  26. *        o Tossed out hard-coded custom copper list; now uses an
  27. *          Intuition screen.  (Drag it!  Amaze your friends!)
  28. *        o Uses Intuition Window to collect mouse click.
  29. *        o Now *closes* GfxBase.
  30. *        o Clipping improved.
  31. *        o Replaced 800-entry sinetable with 1024-entry table.
  32. *        o Angles and spins now forced to even values.
  33. *        o New, more traditional perspective formula.
  34. *        o Reasonably commented.
  35. *        o Busy-wait for bottom-of-frame replaced with copper
  36. *          interrupt.
  37. *        o New amazing stupendous incredible argument parser.
  38. *        o Code speed improved slightly (!)
  39. *        o Has an ARexx port!!!!!
  40. *
  41. * Some dedicated EuroHacker                91??.??
  42. * Leo L. Schwab            (415) 903-9321        9109.12
  43. *  New argument parsing                    9205.09
  44. *  New 1024-entry sinetable                9205.09
  45. *  Functional ARexx                    9205.10
  46. *  BOF copper interrupt                    9205.11
  47. *  1.1 enhancements completed (unreleased)        9210.11
  48. *  Workbench ToolTypes added, parser bug fixed        9210.18
  49. */
  50.  
  51. ****************************************************************************
  52. * Documentation.
  53. *
  54. ******* ES ******************************************
  55. *
  56. *   NAME
  57. *    ES -- EuroStars
  58. *
  59. *   SYNOPSIS
  60. *    ES [MRS][XYZ] <value> [<value> ... ]
  61. *    ES B
  62. *    ES Q    (ARexx only)
  63. *
  64. *   DESCRIPTION
  65. *    ES is a starfield program based on European code that has been
  66. *    massively cleaned up and featurized.  As a result, it doesn't run
  67. *    quite as smoothly on vanilla 68000-based systems, but it's less
  68. *    likely to trash your system.
  69. *
  70. *    ES may be run from the command line or from the Workbench.  When
  71. *    you're finished looking, click either mouse button anywhere on the
  72. *    starfield to exit.
  73. *
  74. *    ES lets you specify how the stars move and rotate.  This is done
  75. *    from the command line, Workbench ToolTypes, or from the ARexx port.
  76. *    For all, the argument syntax is the same.
  77. *
  78. *   ARGUMENTS
  79. *    The M, R, and S operators specify star movement, rotation, and spin
  80. *    respectively.  Movement specifies how many world units the stars are
  81. *    translated each frame.  Rotation specifies a static/initial rotation
  82. *    angle.  Spin specifies the change in rotation for each frame.  The
  83. *    X, Y, and Z specifiers indicate which axes the operators are to
  84. *    apply.  Rotation angles are specified in "EuroHackerGrads."  There
  85. *    are 2048 EHG to a full 360 degree circle.
  86. *
  87. *    The MRS operators must appear before the the XYZ specifiers, and
  88. *    there may be no spaces between them.  Only one MRS operator may
  89. *    appear before a given set of XYZ specifiers.  Following the MRSXYZ
  90. *    command are the actual values to be used.
  91. *
  92. *    It's much easier to understand if you look at the examples.
  93. *
  94. *    In addition to the above, there are two additional arguments that
  95. *    may be used:
  96. *
  97. *    B:    Operate as background server.
  98. *        Ordinarily, ES will exit when you click on its screen.
  99. *        However, if you want to do extensive ARexx operations
  100. *        without user interference, this option may be specified,
  101. *        causing ES to ignore all subsequent mouse events on its
  102. *        screen.  Once backgrounded, ES cannot be un-backgrounded.
  103. *        The only way to terminate a backgrounded ES is with the
  104. *        following command:
  105. *
  106. *    Q:    Quit.
  107. *        When sent as an ARexx command, ES will exit immediately.
  108. *        This option on the CLI command line is meaningless; if
  109. *        present, the entire command line is ignored.
  110. *
  111. *   WORKBENCH
  112. *    ES recognizes Workbench ToolTypes when started from Workbench.  The
  113. *    ToolType strings are identical to the command line arguments.
  114. *    Multiple ToolType strings may be present in the icon; each one will
  115. *    be processed in turn.  Project icons and multiple icon selection are
  116. *    also supported; thus, you can have several "canned" starfields ready
  117. *    to go from a Workbench window.
  118. *
  119. *    Like ARexx commands (see below), the effect of multiple command
  120. *    strings is cumulative.
  121. *
  122. *   AREXX
  123. *    ES features an ARexx port.  The name of the port is EUROSTARS.
  124. *    Commands sent to this port are exactly the same as arguments on the
  125. *    command line.  Malformed commands are returned with RC set to
  126. *    RC_ERROR (10).
  127. *
  128. *    Commands are cumulative; that is, a move command (for example)
  129. *    remains in effect until reset by another move command for the same
  130. *    axis.  Thus, an MX command followed later by an SX command does not
  131. *    cancel the MX command.
  132. *
  133. *   EXAMPLES
  134. *    ES mx 4
  135. *        Move stars 4 units along X axis each frame.
  136. *    ES sxyz 2 -4 6
  137. *        For each frame, spin the X axis 2 EHG, the Y axis -4 EHG,
  138. *        and the Z axis 6 EHG.
  139. *    ES rx 512
  140. *        Rotate X axis 512 EHG and keep it there.
  141. *    ES rx -512 sx 2
  142. *        Start X axis rotated at -512 EHG and add 2 EHG to it each
  143. *        frame.
  144. *    ES mxz 10 0 sxyz 1 1 1
  145. *        Move 10 units along X, zero units along Z, and spin all axes
  146. *        by one EHG each frame.
  147. *    ES mxz sxyz 10 0 1 1 1
  148. *        Identical to the above.
  149. *    ES sxmxsymzsz 1 10 1 0 1
  150. *        Again, identical to the above.
  151. *
  152. *    As you can see, the syntax is very flexible.
  153. *
  154. *   NOTES
  155. *    Despite its nomenclature, the 'B' option does not fork ES into the
  156. *    background; you must use the 'Run' command.
  157. *
  158. *    The coordinate system is right-handed, X axis horizontal, Y axis
  159. *    vertical, Z axis perpendicular to the screen.  Positive rotations
  160. *    are clockwise, and are in Z,Y,X order.
  161. *
  162. *    The default startup values are:
  163. *    MX 0  MY 0  MZ 4   RX 0  RY 0  RZ 0   SX 0  SY 0  SZ 0
  164. *
  165. *   BUGS
  166. *    Though vastly improved for v2.0, it's still a bit slow on 68000-
  167. *    based systems.
  168. *
  169. *    Malformed commands generate a diagnostic string to the CLI.  These
  170. *    strings are not available to ARexx programs or if the program is
  171. *    started from Workbench.  The latter can be particularly annoying, as
  172. *    malformed ToolType strings will cause ES to silently refuse to
  173. *    start.  Sigh...
  174. *
  175. *   AUTHOR
  176. *    Leo L. Schwab  --  New Technologies Group, Inc.
  177. *    BIX:        ewhac
  178. *    Portal:        ewhac
  179. *    InterNet:    ewhac@ntg.com   ..or..   ewhac@well.sf.ca.us
  180. *
  181. ****************************************************************************
  182. * Includes.
  183. *
  184.         include    'exec/types.i'
  185.         include    'exec/memory.i'
  186.         include    'graphics/gfxbase.i'
  187.         include    'hardware/intbits.i'
  188.         include    'intuition/intuition.i'
  189.         include    'libraries/dosextens.i'
  190.         include    'workbench/startup.i'
  191.         include    'workbench/workbench.i'
  192.         include    'rexx/storage.i'
  193.         include    'rexx/errors.i'
  194.  
  195.  
  196. ****************************************************************************
  197. * A couple of simple macros.
  198. *
  199. xlib    MACRO
  200.         XREF    _LVO\1
  201.     ENDM
  202.  
  203. jsrlib    MACRO
  204.         jsr    _LVO\1(a6)
  205.     ENDM
  206.  
  207.  
  208. ****************************************************************************
  209. * External references.
  210. *
  211.         xlib    AllocMem
  212.         xlib    FreeMem
  213.         xlib    AllocSignal
  214.         xlib    FreeSignal
  215.         xlib    AddIntServer
  216.         xlib    RemIntServer
  217.         xlib    OpenLibrary
  218.         xlib    CloseLibrary
  219.         xlib    Forbid
  220.         xlib    Permit
  221.         xlib    WaitPort
  222.         xlib    PutMsg
  223.         xlib    GetMsg
  224.         xlib    ReplyMsg
  225.         xlib    AddPort
  226.         xlib    RemPort
  227.         xlib    FindTask
  228.         xlib    Signal
  229.         xlib    Wait
  230.         xlib    OpenScreen
  231.         xlib    OpenWindow
  232.         xlib    CloseScreen
  233.         xlib    CloseWindow
  234.         xlib    SetPointer
  235.         xlib    MakeScreen
  236.         xlib    GetScreenData
  237.         xlib    RethinkDisplay
  238.         xlib    QueryOverscan
  239.         xlib    LoadRGB4
  240.         xlib    FreeCopList
  241.         xlib    UCopperListInit
  242.         xlib    CWait
  243.         xlib    CMove
  244.         xlib    CBump
  245.         xlib    Output
  246.         xlib    Write
  247.         xlib    CreateProc
  248.         xlib    Lock
  249.         xlib    CurrentDir
  250.         xlib    GetDiskObject
  251.         xlib    FreeDiskObject
  252.  
  253.         xref    _intreq
  254.  
  255.  
  256. ****************************************************************************
  257. * Public symbols (primarily for debugging).
  258. *
  259.         xdef    eventloop
  260.         xdef    Transform
  261.         xdef    NextStar
  262.         xdef    GenMat
  263.         xdef    StarSeg
  264.         xdef    MoveStars
  265.         xdef    DrawStars
  266.         xdef    SinCos
  267.         xdef    ParseArgs
  268.         xdef    delta_x
  269.         xdef    Matrix
  270.         xdef    Screen1_3
  271.         xdef    Screen2_0
  272.  
  273.  
  274. ****************************************************************************
  275. * Symbol Definitions
  276. *
  277. MINBOX        equ    -450
  278. MAXBOX        equ    450
  279. BOXRANGE    equ    MAXBOX-MINBOX+1
  280.  
  281. NSTARS        equ    70        ; Must be even
  282.  
  283. MAGIC        equ    (256<<8)
  284. ZPULL        equ    780
  285.  
  286. SPRBUFSIZ    equ    12
  287.  
  288.  
  289. ****************************************************************************
  290. * And now for the code!
  291. *
  292.         section    EuroStars,code
  293.  
  294. CreatedSix                ; Hi, Stan!
  295.         bsr    ClearBSS    ; Initialize uninitialized data
  296.  
  297.         moveq    #0,d7        ; No error
  298.         move.l    a0,a2        ; Save CLI command line data
  299.         move.l    d0,d2
  300.  
  301.     ;------    Open DOS.
  302.         move.l    (4).w,a6
  303.         lea    DOSName(pc),a1
  304.         moveq    #0,d0
  305.         jsrlib    OpenLibrary
  306.         move.l    d0,DOSBase
  307.         beq    err_dos
  308.  
  309.     ;------    Test CLI vs. Workbench.
  310.         sub.l    a1,a1        ; Find ourselves
  311.         jsrlib    FindTask
  312.         move.l    d0,mpsigtask
  313.         move.l    d0,a0
  314.         tst.l    pr_CLI(a0)    ; Are we a CLI?
  315.         beq.s    WBench        ; No, don't parse command line.
  316.  
  317.     ;------    CLI startup.  Parse arguments.
  318.         move.l    a2,a0        ; Restore CLI command data
  319.         clr.b    0(a0,d2.l)    ; Force NULL at end of command line
  320.         bsr    ParseArgs
  321.         bra.s    errcheck
  322.  
  323.     ;------    Workbench startup.  Get startup message.
  324. WBench        lea    pr_MsgPort(a0),a2
  325.         move.l    a2,a0
  326.         jsrlib    WaitPort
  327.         move.l    a2,a0
  328.         jsrlib    GetMsg
  329.         move.l    d0,WBStartMsg
  330.         bsr    ParseWBArgs
  331.  
  332.     ;------    Now then, did the parser return an error?
  333. errcheck    tst.l    d0
  334.         ble.s    1$        ; (Ignore 'QUIT')
  335.         bsr    PrintCLIStr    ; Print the error
  336.         bra    err_nomemspr    ; Exit (closing DOS)
  337. 1$
  338.     ;------    Allocate memory for blank sprite.
  339.         moveq    #SPRBUFSIZ,d0
  340.         move.l    #MEMF_CHIP!MEMF_CLEAR,d1
  341.         jsrlib    AllocMem
  342.         move.l    d0,sprdat
  343.         beq    err_nomemspr
  344.  
  345.     ;------    Allocate signal for message port.
  346.         moveq    #-1,d0
  347.         jsrlib    AllocSignal
  348.         move.b    d0,mpsigbit
  349.         bmi    err_signal
  350.  
  351.     ;------    Open Graphics
  352.         lea    GfxName(pc),a1
  353.         moveq    #0,d0
  354.         jsrlib    OpenLibrary
  355.         move.l    d0,GBase
  356.         beq    err_gfx
  357.  
  358.     ;------    Open Intuition
  359.         lea    IntuiName(pc),a1
  360.         moveq    #0,d0
  361.         jsrlib    OpenLibrary
  362.         move.l    d0,IBase
  363.         beq    err_intui
  364.  
  365.     ;------    Open screen.  This is done differently based on OS version.
  366.         move.l    d0,a6
  367.         lea    TransformBuff,a3    ; Procure a random buffer...
  368.         cmp.w    #37,LIB_VERSION(a6)    ; What version?
  369.         blt.s    Screen1_3
  370.  
  371.     ;------    Version 2.0.  Open OSCAN_MAX screen.
  372. Screen2_0    move.l    a3,a1        ; Use for Rectangle struct
  373.         moveq    #OSCAN_MAX,d0
  374.         sub.l    a0,a0        ; Zero is LORES_KEY
  375.         jsrlib    QueryOverscan
  376.  
  377.         lea    scr_def(pc),a0
  378.         move.w    ra_MinX(a3),ns_LeftEdge(a0)
  379.         move.w    ra_MinY(a3),ns_TopEdge(a0)
  380.         move.w    ra_MaxX(a3),d0    ; Yes, this is rather the long
  381.         sub.w    ra_MinX(a3),d0    ;  way 'round...
  382.         addq.w    #1,d0
  383.         move.w    ra_MaxY(a3),d1
  384.         sub.w    ra_MinY(a3),d1
  385.         addq.w    #1,d1
  386.         move.w    d0,ns_Width(a0)
  387.         move.w    d1,ns_Height(a0)
  388.         asr.w    #1,d0
  389.         asr.w    #1,d1
  390.         move.w    d0,CenterX
  391.         move.w    d1,CenterY
  392.  
  393.         jsrlib    OpenScreen    ; scr_def still in A0
  394.         move.l    d0,scrptr
  395.         beq    err_scr
  396.         move.l    d0,a2
  397.         bra    OpenWin
  398.  
  399.     ;------    Version 1.3.  Interrogate Workbench screen size.
  400. Screen1_3    move.l    a3,a0        ; Screen buffer
  401.         move.l    #sc_SIZEOF,d0    ; bufsiz
  402.         moveq    #WBENCHSCREEN,d1    ; Screen type
  403.         sub.l    a1,a1        ; NULL
  404.         jsrlib    GetScreenData    ; Tell me about the Workbench screen
  405.  
  406.     ;------    Scale Workbench dimensions down to lores non-lace pixels.
  407.         move.w    sc_ViewPort+vp_DWidth(a3),d0
  408.         btst.b    #7,sc_ViewPort+vp_Modes(a3)    ; Check HIRES bit
  409.         beq.s    1$        ; HIRES?
  410.         asr.w    #1,d0        ; Yes, divide width by two
  411. 1$        move.w    d0,sc_Width(a3)
  412.  
  413.         move.w    sc_ViewPort+vp_DHeight(a3),d0
  414.         btst.b    #2,sc_ViewPort+vp_Modes+1(a3)    ; Check LACE bit
  415.         beq.s    2$        ; LACE?
  416.         asr.w    #1,d0        ; Yes, divide height by two
  417. 2$        move.w    d0,sc_Height(a3)
  418.  
  419.     ;------    If Workbench is bigger than us, we upgrade to its size.
  420.         move.w    scrwide(pc),d0
  421.         cmp.w    sc_Width(a3),d0
  422.         bge.s    3$
  423.         move.w    sc_Width(a3),d0
  424. 3$        move.w    d0,scrwide
  425.         asr.w    #1,d0
  426.         move.w    d0,CenterX
  427.  
  428.         move.w    scrhigh(pc),d0
  429.         cmp.w    sc_Height(a3),d0
  430.         bge.s    4$
  431.         move.w    sc_Height(a3),d0
  432. 4$        move.w    d0,scrhigh
  433.         asr.w    #1,d0
  434.         move.w    d0,CenterY
  435.  
  436.     ;------    Actually open the Screen.
  437.         lea    scr_def(pc),a0
  438.         jsrlib    OpenScreen
  439.         move.l    d0,scrptr
  440.         beq    err_scr
  441.         move.l    d0,a2
  442.  
  443.     ;------    Shove screen's ViewPort into nice-ish overscan position
  444.     ;------    based on Workbench screen's size.
  445.         move.w    scrwide(pc),d0
  446.         sub.w    sc_Width(a3),d0
  447.         asr.w    #1,d0        ; Divide difference by two
  448.         sub.w    d0,sc_ViewPort+vp_DxOffset(a2)    ; Shift screen
  449.  
  450.         move.w    scrhigh(pc),d0
  451.         sub.w    sc_Height(a3),d0
  452.         asr.w    #1,d0
  453.         sub.w    d0,sc_ViewPort+vp_DyOffset(a2)    ; Shift screen
  454.  
  455.     ;------    Open window on screen.
  456. OpenWin        lea    windef(pc),a0
  457.         move.w    scrwide(pc),nw_Width(a0)
  458.         move.w    scrhigh(pc),nw_Height(a0)
  459.         jsrlib    OpenWindow
  460.         move.l    d0,winptr
  461.         beq    err_win
  462.  
  463.     ;------    Set invisible pointer.
  464.         move.l    d0,a0
  465.         move.l    sprdat(pc),a1
  466.         moveq    #0,d0
  467.         moveq    #0,d1
  468.         moveq    #0,d2
  469.         moveq    #0,d3
  470.         jsrlib    SetPointer
  471.  
  472.     ;------    Set local bitplane pointers.
  473.         move.l    sc_BitMap+bm_Planes+0(a2),Plane1ptr
  474.         move.l    sc_BitMap+bm_Planes+4(a2),Plane2ptr
  475.  
  476.     ;------    Allocate memory for Y offset table.
  477.         moveq    #0,d0
  478.         move.w    scrhigh(pc),d0
  479.         add.w    d0,d0
  480.         moveq    #0,d1
  481.         move.l    (4).w,a6
  482.         jsrlib    AllocMem
  483.         move.l    d0,YOffTable
  484.         beq    err_nomemtab
  485.  
  486.         bsr    GenYOffs
  487.  
  488.     ;------    Add Bottom-of-frame copper interrupt.
  489.         lea    MyCopList,a3
  490.         move.l    a3,sc_ViewPort+vp_UCopIns(a2)    ; vp->UCopIns = cl;
  491.         move.l    a3,a0        ; CINIT (cl, 4);
  492.         moveq    #4,d0
  493.         move.l    GBase(pc),a6
  494.         jsrlib    UCopperListInit
  495.  
  496.         move.l    a3,a1        ; CWAIT (cl, scrhigh-1, 0);
  497.         moveq    #0,d0
  498.         move.w    scrhigh(pc),d0
  499.         subq.w    #1,d0        ; Back it off just slightly
  500.         moveq    #0,d1
  501.         jsrlib    CWait
  502.         move.l    a3,a1
  503.         jsrlib    CBump
  504.  
  505.         move.l    a3,a1        ; CMOVE (cl, intreq,
  506.         move.l    #_intreq,d0    ;     INTF_SETCLR | INTF_COPER);
  507.         move.l    #INTF_SETCLR!INTF_COPER,d1
  508.         jsrlib    CMove
  509.         move.l    a3,a1
  510.         jsrlib    CBump
  511.  
  512.         move.l    a3,a1        ; CEND (cl);
  513.         move.l    #10000,d0
  514.         move.l    #255,d1
  515.         jsrlib    CWait
  516.         move.l    a3,a1        ; Not sure this is necessary, but the
  517.         jsrlib    CBump        ;  gfxmacros.h macro does it...
  518.  
  519.     ;------    Recompose display.
  520.         move.l    a2,a0        ; Screen still in A2
  521.         move.l    IBase(pc),a6
  522.         jsrlib    MakeScreen
  523.         jsrlib    RethinkDisplay
  524.  
  525.     ;------    Load colors.
  526.         lea    sc_ViewPort(a2),a0
  527.         lea    colors(pc),a1
  528.         moveq    #4,d0
  529.         move.l    GBase(pc),a6
  530.         jsrlib    LoadRGB4
  531.  
  532.     ;------    Create sub-process to actually render stars.
  533.         move.l    mpsigtask(pc),a0
  534.         moveq    #0,d2
  535.         move.b    LN_PRI(a0),d2    ; Priority
  536.         subq.l    #1,d2        ; (Nudge *BELOW* creator)
  537.         lea    StarSeg(pc),a0
  538.         move.l    a0,d3        ; SegList pointer
  539.         lsr.l    #2,d3        ; (Convert to BPTR)
  540.         lea    ESName(pc),a0
  541.         move.l    a0,d1        ; Process name
  542.         move.l    #4096,d4    ; Stack size
  543.         move.l    DOSBase(pc),a6
  544.         jsrlib    CreateProc
  545.         move.l    d0,d1
  546.         beq    err_proc
  547.  
  548.         sub.l    #pr_MsgPort,d1    ; Compute address of task
  549.         move.l    d1,StarTask    ; Store it
  550.  
  551.     ;------    Launch subprocess with startup message.
  552.         move.l    d0,a0
  553.         lea    startmsg(pc),a1
  554.         move.l    (4).w,a6
  555.         jsrlib    PutMsg
  556.  
  557.     ;------    Publish message port.
  558.         lea    rexxport(pc),a1
  559.         jsrlib    AddPort
  560.  
  561.  
  562.     ;------    Wait for ARexx and Intuition events.
  563.         bsr    HandleEvents
  564.  
  565.  
  566.     ;------    Remove port and flush all pending messages.
  567.         jsrlib    Forbid        ; STOP!
  568.         lea    rexxport(pc),a2
  569.         move.l    a2,a1
  570.         jsrlib    RemPort        ; Pull port from list
  571.         moveq    #RC_FATAL,d2
  572.  
  573. flushloop    move.l    a2,a0
  574.         jsrlib    GetMsg        ; Get message, if any
  575.         tst.l    d0
  576.         beq.s    1$        ; No message, leave loop
  577.         move.l    d0,a1
  578.         move.l    d2,rm_Result1(a1)    ; Die die die
  579.         clr.l    rm_Result2(a1)
  580.         jsrlib    ReplyMsg    ; Reply failed message
  581.         bra.s    flushloop
  582. 1$
  583.         jsrlib    Permit        ; Okay, go ahead.
  584.  
  585.     ;------    Send kill signal to stars process.
  586.         moveq    #0,d0
  587.         bset    #SIGBREAKB_CTRL_C,d0
  588.         move.l    StarTask(pc),a1
  589.         jsrlib    Signal
  590.  
  591.     ;------    Wait for startup message to return.
  592.         lea    rexxport(pc),a0
  593.         jsrlib    WaitPort
  594.  
  595.  
  596.     ;------    Cleanup and exit.
  597. err_proc    move.l    GBase(pc),a6    ; Delete UCopList by hand
  598.         move.l    scrptr(pc),a0    ;  (required for 1.3)
  599.         lea    sc_ViewPort+vp_UCopIns(a0),a0
  600.         move.l    (a0),a1
  601.         clr.l    (a0)        ; Keep system from freeing it, too
  602.         move.l    ucl_FirstCopList(a1),a0
  603.         jsrlib    FreeCopList
  604.  
  605.         move.l    (4).w,a6    ; Delete Y Offset table
  606.         move.l    YOffTable(pc),a1
  607.         moveq    #0,d0
  608.         move.w    scrhigh,d0
  609.         add.w    d0,d0
  610.         jsrlib    FreeMem
  611. err_nomemtab    move.l    IBase(pc),a6    ; Close window
  612.         move.l    winptr(pc),a0
  613.         jsrlib    CloseWindow
  614. err_win        move.l    scrptr(pc),a0
  615.         jsrlib    CloseScreen
  616. err_scr        move.l    a6,a1
  617.         move.l    (4).w,a6
  618.         jsrlib    CloseLibrary    ; Close Intuition
  619. err_intui    move.l    GBase(pc),a1
  620.         jsrlib    CloseLibrary    ; Close Graphics
  621. err_gfx        moveq    #0,d0
  622.         move.b    mpsigbit(pc),d0
  623.         jsrlib    FreeSignal    ; Free msgport signal
  624. err_signal    move.l    sprdat(pc),a1
  625.         moveq    #SPRBUFSIZ,d0
  626.         jsrlib    FreeMem
  627. err_nomemspr    move.l    DOSBase(pc),a1
  628.         jsrlib    CloseLibrary
  629. err_dos
  630.         move.l    WBStartMsg(pc),d0    ; Reply Workbench startup
  631.         beq.s    xit            ;  if present.
  632.  
  633.         jsrlib    Forbid        ; Prevent Workbench from unloading
  634.         move.l    d0,a1        ;  us before we've actually exited
  635.         jsrlib    ReplyMsg
  636.         clr.l    d0
  637.  
  638. xit        rts
  639.  
  640.  
  641. ****************************************************************************
  642. * ARexx message and window event processing loop.
  643. *
  644. HandleEvents
  645.     ;------    Compute signal flag for window port.
  646.         moveq    #0,d2
  647.         move.l    winptr(pc),a0
  648.         move.l    wd_UserPort(a0),a0
  649.         move.b    MP_SIGBIT(a0),d0
  650.         bset.l    d0,d2
  651.  
  652.     ;------    Compute signal flag for ARexx port.
  653.         move.b    mpsigbit(pc),d0
  654.         bset.l    d0,d2
  655.  
  656.     ;------    Wait for something to happen.
  657. eventloop    move.l    d2,d0
  658.         jsrlib    Wait
  659.  
  660.     ;------    Check for ARexx messages.
  661.         moveq    #RC_ERROR,d3
  662.  
  663. 0$        lea    rexxport(pc),a0
  664.         jsrlib    GetMsg
  665.         tst.l    d0        ; Message present?
  666.         beq.s    9$        ; No, fall off
  667.  
  668.         move.l    d0,a2
  669.         move.l    ARG0(a2),a0    ; Get argument string
  670.         bsr    ParseArgs    ; Parse it
  671.         move.l    d0,d7        ; Was there an error?
  672.         ble.s    1$        ; No
  673.  
  674.         move.l    d3,rm_Result1(a2)    ; Yes, store error
  675.         bra.s    2$
  676.  
  677. 1$        clr.l    rm_Result1(a2)
  678. 2$        clr.l    rm_Result2(a2)    ; Result2 always NULL
  679.         move.l    a2,a1
  680.         jsrlib    ReplyMsg    ; Send message back
  681.         bra.s    0$        ; Next message, please
  682. 9$
  683.     ;------    Was that parser return a REXX request for death?
  684.         tst.l    d7
  685.         bmi.s    Rexxit        ; Why, yes it was!
  686.  
  687.     ;------    Check for window events.
  688.         move.l    winptr(pc),a0
  689.         move.l    wd_UserPort(a0),a0
  690.         jsrlib    GetMsg        ; Check port
  691.         tst.l    d0        ; Something there?
  692.         beq.s    eventloop    ; No, go to sleep
  693.         move.l    d0,a1        ; Yup, reply it
  694.         jsrlib    ReplyMsg
  695.  
  696.     ;------    Window event arrived.  If we are a background server, ignore
  697.     ;------    the event.  Elsewise, return.
  698.         move.w    BackServ(pc),d0    ; Just to set flags
  699.         bne.s    eventloop
  700.  
  701. Rexxit        rts            ; User wants us dead, dammit.
  702.  
  703.  
  704. ****************************************************************************
  705. * Welcome to the actual stars code.
  706. *
  707.         cnop    0,4
  708.  
  709. StarSeg        dc.l    0        ; Phony NextSeg pointer
  710.  
  711.     ;------    Entry point.
  712.         move.l    (4).w,a6
  713.         sub.l    a1,a1
  714.         jsrlib    FindTask        ; Get pointer to this task.
  715.         move.l    d0,a0
  716.         lea    pr_MsgPort(a0),a2    ; Get pointer to MsgPort
  717.  
  718.     ;------    Wait for startup message.
  719.         move.l    a2,a0
  720.         jsrlib    WaitPort
  721.         move.l    a2,a0
  722.         jsrlib    GetMsg
  723.         move.l    d0,StarMsg
  724.  
  725.     ;------    Compute sigmask.
  726.         moveq    #0,d0
  727.         bset.l    #SIGBREAKB_CTRL_C,d0
  728.         bset.l    #SIGBREAKB_CTRL_F,d0    ; BOF will happen here.
  729.         move.l    d0,StarSigMask
  730.  
  731.     ;------    Install interrupt server.
  732.         moveq    #INTB_COPER,d0
  733.         lea    BOFintrnode(pc),a1
  734.         jsrlib    AddIntServer
  735.  
  736.     ;------    Main star loop.
  737. mainloop    bsr    AddSpins
  738.         bsr    GenMat
  739.         bsr    Transform
  740.         bsr.s    MoveStars
  741.  
  742.         move.l    StarSigMask(pc),d0
  743.         jsrlib    Wait        ; Wait for BOF or kill signal
  744.         move.l    d0,StarSigs
  745.  
  746.         bsr    EraseStars    ; Do this in any case
  747.         bsr    DrawStars
  748.  
  749.         move.l    StarSigs(pc),d0
  750.         btst.l    #SIGBREAKB_CTRL_C,d0
  751.         beq.s    mainloop
  752.  
  753.     ;------    Got kill signal from above.  Remove interrupt server,
  754.     ;------    reply startup and exit.
  755.         jsrlib    Forbid        ; HA!  MINE!
  756.         moveq    #INTB_COPER,d0
  757.         lea    BOFintrnode(pc),a1
  758.         jsrlib    RemIntServer
  759.  
  760.         move.l    StarMsg(pc),a1
  761.         jmp    _LVOReplyMsg(a6)    ; Poof!  Bye...
  762.  
  763.  
  764.  
  765. ****************************************************************************
  766. * Move the stars
  767. *
  768. MoveStars    lea    XCoords(pc),a0
  769.         lea    YCoords(pc),a1
  770.         lea    ZCoords(pc),a2
  771.         move.w    delta_x(pc),d0
  772.         move.w    delta_y(pc),d1
  773.         move.w    delta_z(pc),d2
  774.         move.w    #BOXRANGE,d4
  775.         moveq    #NSTARS-1,d7
  776.  
  777. 0$        move.w    (a0),d3
  778.         add.w    d0,d3        ; Add move delta
  779.         cmp.w    #MAXBOX,d3    ; Too big?
  780.         bgt.s    1$
  781.         cmp.w    #MINBOX,d3    ; Too small?
  782.         bge.s    2$
  783.         add.w    d4,d3        ; Wrap up
  784.         bra.s    2$
  785. 1$        sub.w    d4,d3        ; Wrap down
  786. 2$        move.w    d3,(a0)+
  787.  
  788.         move.w    (a1),d3
  789.         add.w    d1,d3
  790.         cmp.w    #MAXBOX,d3
  791.         bgt.s    11$
  792.         cmp.w    #MINBOX,d3
  793.         bge.s    22$
  794.         add.w    d4,d3
  795.         bra.s    22$
  796. 11$        sub.w    d4,d3
  797. 22$        move.w    d3,(a1)+
  798.  
  799.         move.w    (a2),d3
  800.         add.w    d2,d3
  801.         cmp.w    #MAXBOX,d3
  802.         bgt.s    111$
  803.         cmp.w    #MINBOX,d3
  804.         bge.s    222$
  805.         add.w    d4,d3
  806.         bra.s    222$
  807. 111$        sub.w    d4,d3
  808. 222$        move.w    d3,(a2)+
  809.  
  810.         dbra    d7,0$
  811.  
  812.         rts
  813.  
  814.  
  815. ****************************************************************************
  816. * Star rendering routines.
  817. *
  818. * This too has undergone a re-write since 1.0.  A BSET instruction is now
  819. * used to plot the star directly into the bitmap.  The Y-offset into the
  820. * bitmap is now fetched from a pre-computed table to save on a multiply.
  821. * A change to the in-memory representation of the projected points saved
  822. * a few cycles in memory fetches.  Further, rendering is now done with bytes
  823. * rather than words (since BSETs to memory are only byte-wide); any loss on
  824. * higher-order processors is made up for by the faster clock.
  825. *
  826. * EraseStars underwent a kooky change since it appears to be the blocking
  827. * factor for clean rendering on a 68000.  Getting even faster would mean
  828. * major towering, which falls under the law of diminshing returns.
  829. *
  830. EraseStars    moveq    #0,d0
  831.         move.l    Plane1ptr(pc),a1
  832.         move.l    Plane2ptr(pc),a2
  833.         lea    PlaneOffsets,a4
  834.         moveq    #(NSTARS>>1)-1,d7    ; As the programmer :-), I
  835.                     ;  guarantee the count will be even
  836.  
  837. 1$        move.l    (a4)+,d1    ; Grab two offsets at once
  838.         move.b    d0,0(a1,d1.w)    ; Blast entire byte
  839.         move.b    d0,0(a2,d1.w)
  840.         swap    d1        ; Switch to other offset
  841.         move.b    d0,0(a1,d1.w)    ; Blast entire byte
  842.         move.b    d0,0(a2,d1.w)
  843.         dbra    d7,1$
  844.  
  845.         rts
  846.  
  847.  
  848. DrawStars    lea    TransformBuff,a0    ; Coords in YXZ order
  849.         move.l    YOffTable(pc),a1
  850.         lea    PlaneOffsets,a3
  851.         move.l    Plane1ptr(pc),a2
  852.         move.l    Plane2ptr(pc),a4
  853.         moveq    #NSTARS-1,d7
  854.         move.w    scrhigh(pc),d4
  855.         move.w    scrwide(pc),d5
  856. NextDraw    move.w    (a0)+,d1    ; Load and check Y value
  857.         bmi.s    clipped_y
  858.         cmp.w    d4,d1
  859.         bge.s    clipped_y
  860.  
  861.         move.w    (a0)+,d0    ; Load and check X value
  862.         bmi.s    clipped_x
  863.         cmp.w    d5,d0
  864.         bge.s    clipped_x
  865.  
  866.         move.w    d0,d2
  867.         not.w    d0        ; Invert X for BSET bit positon
  868.         lsr.w    #3,d2        ; Compute byte offset in line
  869.         add.w    d1,d1
  870.         move.w    0(a1,d1.w),d1    ; Get Y offset from table
  871.         add.w    d1,d2
  872.         move.w    d2,(a3)+    ; Store computed offset
  873.         move.w    (a0)+,d6    ; Load Z
  874.         cmp.w    #-176,d6    ; Z closer than this?
  875.         ble.s    1$        ; No, draw just plane 1 (dim)
  876.  
  877.         bset    d0,0(a4,d2.w)    ; This plane definitely gets written
  878.         cmp.w    #130,d6        ; Very close?
  879.         ble.s    2$        ; No
  880. 1$        bset    d0,0(a2,d2.w)    ;    Yes; draw brightest value
  881. 2$
  882.         dbra    d7,NextDraw
  883.  
  884.         rts
  885.  
  886. clipped_y    addq.w    #2,a0        ; Skip unread x
  887. clipped_x    addq.w    #2,a0        ; Skip unread z
  888.         clr.w    (a3)+
  889.         dbra    d7,NextDraw
  890.  
  891.         rts
  892.  
  893.  
  894. ****************************************************************************
  895. * This is the biggie.
  896. *
  897. * This has been completely re-written, and where the biggest speed gains
  898. * were realized.  It used to be three discrete rotations.  Now it's a full
  899. * matrix operation.
  900. *
  901. * The source XYZ values are loaded into D0-D2.  The resulting XYZ values are
  902. * left in D3-D5.  The matrix is stored in column-major ZYX order.  This is
  903. * done to facilitate early rejection of Z values behind the camera (though
  904. * I don't yet make use of that).
  905. *
  906. * The matrix elements are in 2.14 bit fixed-point notation.  The numbers in
  907. * the coordinate array are straight integers.
  908. *
  909. Transform    lea    XCoords(pc),a0
  910.         lea    YCoords(pc),a1
  911.         lea    ZCoords(pc),a2
  912.         lea    TransformBuff,a4
  913.         moveq    #NSTARS-1,d7
  914.         move.l    #MAGIC,d6
  915.         move.w    #ZPULL,a5    ; Being used for storage
  916.  
  917.     ;------    Load vertex and matrix.
  918. NextStar    move.w    (a0)+,d0    ; Fetch X, Y, and Z
  919.         move.w    (a1)+,d1
  920.         move.w    (a2)+,d2
  921.         lea    Matrix(pc),a3    ; Fetch matrix
  922.  
  923.     ;------    Multiply vertex through matrix.
  924.     ;------    First column is Z.
  925.         move.w    d0,d5        ; X
  926.         muls    (a3)+,d5    ;   * *mat++
  927.         move.w    d1,d4        ; Y
  928.         muls    (a3)+,d4    ;   * *mat++
  929.         add.l    d4,d5        ;        Accumulate to D5
  930.         move.w    d2,d4        ; Z
  931.         muls    (a3)+,d4    ;   * *mat++
  932.         add.l    d4,d5        ;        Accumulate to D5
  933.         swap    d5
  934.         rol.l    #2,d5        ; D5 >>= 14;
  935.  
  936.     ;------    Second column is Y.
  937.         move.w    d0,d4        ; X
  938.         muls    (a3)+,d4    ;   * *mat++
  939.         move.w    d1,d3        ; Y
  940.         muls    (a3)+,d3    ;   * *mat++
  941.         add.l    d3,d4        ;        Accumulate to D4
  942.         move.w    d2,d3        ; Z
  943.         muls    (a3)+,d3    ;   * *mat++
  944.         add.l    d3,d4        ;        Accumulate to D4
  945.         swap    d4
  946.         rol.l    #2,d4        ; D4 >>= 14;
  947.  
  948.     ;------    Third column is X.
  949.         move.w    d0,d3        ; X
  950.         muls    (a3)+,d3    ;   * *mat++
  951.         move.w    d1,d0        ; Y (original X no longer needed)
  952.         muls    (a3)+,d0    ;   * *mat++
  953.         add.l    d0,d3        ;        Accumulate to D3
  954.         move.w    d2,d0        ; Z
  955.         muls    (a3)+,d0    ;   * *mat++
  956.         add.l    d0,d3        ;        Accumulate to D3
  957.         swap    d3
  958.         rol.l    #2,d3        ; D3 >>= 14;
  959.  
  960. ****************
  961. * Here is performed the perspective projection.
  962. *
  963. * Normally, this is accomplished by dividing both X and Y by the Z
  964. * coordinate.  However, in this case, only one division is performed to
  965. * calculate a fixed-point scaling factor, which is then multiplied by the
  966. * X and Y values.  This is done because multiplication is cheaper than
  967. * division.  The perspective scalar is:
  968. *
  969. *        MAGIC
  970. *    -------------
  971. *    - (Z - ZPULL)
  972. *
  973. * The subtraction from Z is to "pull" the stars away from the camera (which
  974. * is at Z == 0) so that they'll be visible.  The negation effectively flips
  975. * the Z axis, which makes the calculation easier (trust me).  MAGIC and
  976. * ZPULL are currently set to 256 and 780 respectively.  The 256 is a number
  977. * I pulled out of Thin Air.  (So's the 780, for that matter...)  Feel free
  978. * to play with them to see what happens.
  979. *
  980. * The projected points are stored in YXZ order.
  981. *
  982.     ;------    Compute scalar.
  983.         move.l    d6,d0        ; MAGIC
  984.         move.w    a5,d1        ; ZPULL
  985.         sub.w    d5,d1        ;    - Z
  986.         ble.s    BehindCamera
  987.         divu    d1,d0        ; == 256 / (ZPULL - Z)
  988.         bvs.s    BehindCamera    ; Shunt wild division
  989.  
  990.     ;------    Multiply scalar by X and Y components.
  991.         move.w    d4,d1        ; Y
  992.         muls    d0,d1        ;   * 256 / (ZPULL - Z)
  993.         lsr.l    #8,d1        ; (Unavoidable.  Ack!)
  994.         add.w    CenterY(pc),d1
  995.         move.w    d1,(a4)+    ; Y store
  996.  
  997.         move.w    d3,d1        ; X
  998.         muls    d0,d1        ;   * 256 / (ZPULL - Z)
  999.         lsr.l    #8,d1
  1000.         add.w    CenterX(pc),d1
  1001.         move.w    d1,(a4)+    ; X store
  1002.  
  1003.         move.w    d5,(a4)+    ; Z store (for pixel brightness)
  1004.  
  1005.         dbra    d7,NextStar
  1006.  
  1007.         rts
  1008.  
  1009.     ;------    Whoops!  Behind the camera.  Force an invisible point.
  1010. BehindCamera    moveq    #-1,d1
  1011.         move.l    d1,(a4)+    ; X and Y store
  1012.         move.w    d5,(a4)+    ; Z store
  1013.         dbra    d7,NextStar
  1014.  
  1015.         rts
  1016.  
  1017.  
  1018.  
  1019. ****************************************************************************
  1020. * Generate a matrix.
  1021. *
  1022. * This routine generates a three-rotation matrix all at once, in ZYX order.
  1023. * Rotations are anti-clockwise.
  1024. *
  1025. GenMat        move.w    theta_z(pc),d0    ; Collect sines and cosines
  1026.         bsr    SinCos
  1027.         move.w    d0,d4        ; sinZ
  1028.         move.w    d1,d5        ; cosZ
  1029.         move.w    theta_y(pc),d0
  1030.         bsr    SinCos
  1031.         move.w    d0,d2        ; sinY
  1032.         move.w    d1,d3        ; cosY
  1033.         move.w    theta_x(pc),d0
  1034.         bsr    SinCos
  1035.  
  1036.         lea    Matrix(pc),a0    ; Point at matrix
  1037.  
  1038.     ;------    Compute first column Z.
  1039.     ;------    sinX * sinZ - cosX * sinY * cosZ
  1040.         move.w    d0,d7        ; sinX
  1041.         muls    d4,d7        ;      * sinZ
  1042.         move.w    d1,d6        ; cosX
  1043.         muls    d2,d6        ;      * sinY
  1044.         swap    d6
  1045.         rol.l    #2,d6
  1046.         move.w    d6,a1        ;        (Save for later)
  1047.         muls    d5,d6        ;           * cosZ
  1048.         sub.l    d6,d7
  1049.         swap    d7
  1050.         rol.l    #2,d7        ; D7 >>= 14
  1051.         move.w    d7,(a0)+    ;            (Store)
  1052.  
  1053.     ;------    sinX * cosZ + cosX * sinY * sinZ
  1054.         move.w    d0,d6        ; sinX
  1055.         muls    d5,d6        ;      * cosZ
  1056.         move.w    a1,d7        ; cosX * sinY
  1057.         muls    d4,d7        ;          * sinZ
  1058.         add.l    d6,d7
  1059.         swap    d7
  1060.         rol.l    #2,d7
  1061.         move.w    d7,(a0)+    ;            (Store)
  1062.  
  1063.     ;------    cosX * cosY
  1064.         move.w    d1,d7        ; cosX
  1065.         muls    d3,d7        ;      * cosY
  1066.         swap    d7
  1067.         rol.l    #2,d7
  1068.         move.w    d7,(a0)+    ;            (Store)
  1069.  
  1070.     ;------    Compute second column Y.
  1071.     ;------    cosX * sinZ + sinX * sinY * cosZ
  1072.         move.w    d1,d7        ; cosX
  1073.         muls    d4,d7        ;      * sinZ
  1074.         move.w    d0,d6        ; sinX
  1075.         muls    d2,d6        ;      * sinY
  1076.         swap    d6
  1077.         rol.l    #2,d6
  1078.         move.w    d6,a1        ;        (Save for later)
  1079.         muls    d5,d6        ;          * cosZ
  1080.         add.l    d6,d7
  1081.         swap    d7
  1082.         rol.l    #2,d7
  1083.         move.w    d7,(a0)+    ;            (Store)
  1084.  
  1085.     ;------    cosX * cosZ - sinX * sinY * sinZ
  1086.         move.w    d1,d7        ; cosX
  1087.         muls    d5,d7        ;      * cosZ
  1088.         move.w    a1,d6        ; sinX * sinY
  1089.         muls    d4,d6        ;          * sinZ
  1090.         sub.l    d6,d7
  1091.         swap    d7
  1092.         rol.l    #2,d7
  1093.         move.w    d7,(a0)+    ;            (Store)
  1094.  
  1095.     ;------    -sinX * cosY
  1096.         move.w    d0,d7        ;  sinX
  1097.         neg.w    d7        ; -
  1098.         muls    d3,d7        ;    * cosY
  1099.         swap    d7
  1100.         rol.l    #2,d7
  1101.         move.w    d7,(a0)+    ;            (Store)
  1102.  
  1103.     ;------    Compute third column X.
  1104.     ;------    cosY * cosZ
  1105.         move.w    d3,d7        ; cosY
  1106.         muls    d5,d7        ;      * cosZ
  1107.         swap    d7
  1108.         rol.l    #2,d7
  1109.         move.w    d7,(a0)+    ;            (Store)
  1110.  
  1111.     ;------    -cosY * sinZ
  1112.         move.w    d3,d7        ;  cosY
  1113.         neg.w    d7        ; -
  1114.         muls    d4,d7        ;    * sinZ
  1115.         swap    d7
  1116.         rol.l    #2,d7
  1117.         move.w    d7,(a0)+    ;            (Store)
  1118.  
  1119.     ;------    sinY
  1120.         move.w    d2,(a0)+    ;            (Store)
  1121.  
  1122.     ;------    Phew!  We're outa here.
  1123.         rts
  1124.  
  1125.  
  1126. ****************************************************************************
  1127. * Sine/Cosine calculator.  Nothing amazing here, just a table lookup.
  1128. *
  1129. * This got a lot more complicated for no good reason :-).  The sine/cosine
  1130. * table ranges from 0-90°.  The code selects the proper values and negates
  1131. * them based on the quadrant in which the angle lies.  2048 == 360 degrees.
  1132. * Sine table entries are represented using 14 bit fixed point fractions.
  1133. *
  1134. * Angle passed in D0.  May now be an odd number.
  1135. * Returns sine in D0, cosine in D1.
  1136. *
  1137. SinCos        move.w    d2,-(sp)
  1138.  
  1139.         add.w    d0,d0        ; Word offset
  1140.         lea    SineTable(pc),a5
  1141.         move.w    d0,d2        ; Copy
  1142.         and.w    #1024-1,d0    ; Clip to 90°
  1143.         move.w    #1024,d1    ; d0 == ang
  1144.         sub.w    d0,d1        ; d1 == gna
  1145.  
  1146.         move.w    0(a5,d0.w),d0    ; Fetch sine candidate
  1147.         move.w    0(a5,d1.w),d1    ; Fetch cosine candidate
  1148.  
  1149.     ;------    Determine which is sine and which is cosine.
  1150.         lsl.w    #5,d2        ; Shift quadrant bits into Carry and
  1151.                     ;  Minus flags.
  1152.         bpl.s    1$        ; First or third quadrant?
  1153.         exg    d0,d1        ; Yes, exchange values
  1154. 1$
  1155.     ;------    Is sine negative?
  1156.         bcc.s    2$        ; Third or fourth quadrants?
  1157.         neg.w    d0        ; Yes, negate si(g)ne
  1158.  
  1159.     ;------    Is cosine negative?  We test for this two ways, depending on
  1160.     ;------    the result of the previous test.
  1161.         tst.w    d2        ; Quadrant 3?
  1162.         bpl.s    88$        ; Yes, negate cosine
  1163.         bra.s    99$
  1164.  
  1165. 2$        tst.w    d2        ; Quadrant 2?
  1166.         bpl.s    99$
  1167. 88$        neg.w    d1        ; Yes, negate cosine
  1168.  
  1169. 99$        move.w    (sp)+,d2
  1170.         rts
  1171.  
  1172.  
  1173. ****************************************************************************
  1174. * Add spins to current rotation angles.  Clip to 360° circle.
  1175. *
  1176. AddSpins    move.w    #2048-1,d1    ; 360° == 2048 EHG
  1177.         lea    theta_x(pc),a0
  1178.         lea    spin_x(pc),a1
  1179.  
  1180.         move.w    (a0),d0        ; Get angle
  1181.         add.w    (a1)+,d0    ; Add spin
  1182.         and.w    d1,d0        ; Clip to 360°
  1183.         move.w    d0,(a0)+    ; Store it back
  1184.  
  1185.         move.w    (a0),d0
  1186.         add.w    (a1)+,d0
  1187.         and.w    d1,d0
  1188.         move.w    d0,(a0)+
  1189.  
  1190.         move.w    (a0),d0
  1191.         add.w    (a1),d0
  1192.         and.w    d1,d0
  1193.         move.w    d0,(a0)
  1194.  
  1195.         rts
  1196.  
  1197.  
  1198.  
  1199. ****************************************************************************
  1200. * New ParseArgs.  More flexible!  Less filling!
  1201. * Added 9202.20        Finished 9205.09
  1202. *
  1203. *    A0:  Argument string.
  1204. *
  1205. *    As the options are parsed, the destination address of the value is
  1206. *    pushed on a queue.  As values are acquired, the address is pulled,
  1207. *    and the value stored there.  Imbalances are checked and reported.
  1208. *
  1209. * SYNOPSIS
  1210. *    [MRS][XYZ] <value> [ <value> ... ]
  1211. *
  1212. *    Only one M, R, or S qualifier may accompany XYZ specifiers.  They
  1213. *    may be specified in any order, and the values need not immediately
  1214. *    follow them.
  1215. *
  1216. * OPTIONS
  1217. *    M: Move; specify translation
  1218. *    R: Rotate; specify initial rotation
  1219. *    S: Spin; specify spin velocities
  1220. *
  1221.  
  1222. ParseArgs    movem.l    d2/d7/a2-a5,-(sp)
  1223.         sub.l    a3,a3        ; Mode (NULL)
  1224.         move.l    sp,a4        ; Stacksave
  1225.         move.l    sp,a5        ; Pop pointer
  1226.  
  1227.     ;------    Copy active variables to workspace.
  1228.         lea    delta_x(pc),a1
  1229.         lea    wrk_delta(pc),a2
  1230.         move.l    (a1)+,(a2)+
  1231.         move.l    (a1)+,(a2)+
  1232.         move.l    (a1)+,(a2)+
  1233.         move.l    (a1)+,(a2)+
  1234.         move.w    (a1),(a2)
  1235.  
  1236.     ;------    Main parsing loop.
  1237. getchar        moveq    #0,d0
  1238.         move.b    (a0)+,d0    ; getchar()
  1239.         beq    EndOfString
  1240.         cmp.b    #'a',d0        ; Lower case?
  1241.         blo.s    0$
  1242.         sub.b    #'a'-'A',d0    ; Convert to upper case
  1243. 0$
  1244.     ;------    Test for whitespace.
  1245.         cmp.b    #' ',d0
  1246.         beq.s    whitespace
  1247.         cmp.b    #9,d0        ; TAB
  1248.         beq.s    whitespace
  1249.         cmp.b    #10,d0        ; Newline
  1250.         beq.s    whitespace
  1251.  
  1252.     ;------    Test for numeric.
  1253.         cmp.b    #'-',d0        ; Leading minus
  1254.         beq.s    numeric
  1255.         cmp.b    #'0',d0
  1256.         blo.s    3$
  1257.         cmp.b    #'9',d0
  1258.         bls.s    numeric
  1259. 3$
  1260.     ;------    Test for [B]ackground command.
  1261.         cmp.b    #'B',d0
  1262.         bne.s    1$
  1263.         move.w    d0,BackServ    ; All it has to be is non-zero
  1264.         bra    UnWindOK    ; Ignore rest of string
  1265. 1$
  1266.     ;------    Test for [Q]uit command.
  1267.         cmp.b    #'Q',d0
  1268.         bne.s    2$
  1269.         moveq    #-1,d0        ; Tell upstairs we need to quit
  1270.         bra    UnWind        ; Ignore rest of string
  1271. 2$
  1272.     ;------    Test for '?' help.
  1273.         moveq    #ERR_HELP,d7
  1274.         cmp.b    #'?',d0
  1275.         beq    ParseError
  1276.  
  1277.     ;------    Test for 'XYZ'.
  1278.         cmp.b    #'X',d0
  1279.         blo.s    4$
  1280.         cmp.b    #'Z',d0
  1281.         bls.s    GotXYZ
  1282. 4$
  1283.     ;------    Test for 'MRS'; set mode if present.
  1284.         cmp.b    #'M',d0
  1285.         bne.s    11$
  1286.         lea    wrk_delta(pc),a3    ; Set mode
  1287.         bra.s    getchar
  1288. 11$
  1289.         cmp.b    #'R',d0
  1290.         bne.s    22$
  1291.         lea    wrk_theta(pc),a3    ; Set mode
  1292.         bra.s    getchar
  1293. 22$
  1294.         cmp.b    #'S',d0
  1295.         bne    33$
  1296.         lea    wrk_spin(pc),a3        ; Set mode
  1297.         bra    getchar
  1298. 33$
  1299.     ;------    Dunno what this is; error.
  1300.         moveq    #ERR_SYNTAX,d7
  1301.         bra    ParseError
  1302.  
  1303.  
  1304.     ;------    Process whitespace.
  1305. whitespace    sub.l    a3,a3        ; NULL out mode
  1306.         bra    getchar
  1307.  
  1308.  
  1309.     ;------    Process numerics.
  1310. numeric        subq.w    #1,a0        ; ungetchar()
  1311.         bsr.s    GatherNum    ; Parsed value returned in D0
  1312.  
  1313.         moveq    #ERR_EXTRAVAL,d7
  1314.         cmpa.l    sp,a5        ; Are there values yet to be poked?
  1315.         beq    ParseError    ; Nope, too many values.
  1316.         move.l    -(a5),a1    ; Get address to poke
  1317.         move.w    d0,(a1)        ; Write value.
  1318.  
  1319.         bra    getchar
  1320.  
  1321.  
  1322.     ;------    Process presence of 'XYZ'.
  1323. GotXYZ        moveq    #ERR_NOMODE,d7
  1324.         move.l    a3,d1        ; Mode set?
  1325.         beq    ParseError    ; No, user forgot MRS qualifier
  1326.  
  1327.         sub.b    #'X',d0        ; Compute index
  1328.         add.w    d0,d0        ; Compute word offset
  1329.         add.l    a3,d0        ; Add "mode" to get final address
  1330.         move.l    d0,-(sp)    ; Push address
  1331.         bra    getchar
  1332.  
  1333.  
  1334.     ;------    End of string; perform sanity checks and return.
  1335. EndOfString    moveq    #ERR_MISSINGVAL,d7
  1336.         cmpa.l    sp,a5        ; Is stack empty?
  1337.         bne.s    ParseError
  1338.  
  1339.     ;------    Copy new values to active variables.
  1340.         lea    wrk_delta(pc),a0
  1341.         lea    delta_x(pc),a1
  1342.         move.l    (a0)+,(a1)+
  1343.         move.l    (a0)+,(a1)+
  1344.         move.l    (a0)+,(a1)+
  1345.         move.l    (a0)+,(a1)+
  1346.         move.w    (a0),(a1)
  1347.  
  1348. UnWindOK    moveq    #0,d0        ; No error
  1349. UnWind        move.l    a4,sp        ; Restore stack pointer
  1350.         movem.l    (sp)+,d2/d7/a2-a5
  1351.         rts            ; Back to you, Brian...
  1352.  
  1353.  
  1354. ****************
  1355. * Gather decimal number.
  1356. *
  1357. GatherNum    moveq    #0,d0
  1358.         moveq    #0,d1
  1359.         moveq    #0,d2        ; negative flag
  1360.  
  1361.     ;------    Gather chars.  Test for whitespace first.
  1362. numloop        move.b    (a0)+,d1
  1363.         beq.s    11$        ; NULL; EOL
  1364.         cmp.b    #' ',d1
  1365.         beq.s    11$
  1366.         cmp.b    #9,d1        ; TAB
  1367.         beq.s    11$
  1368.         cmp.b    #10,d1        ; Newline
  1369.         beq.s    11$
  1370.  
  1371.     ;------    Check for unary minus.
  1372.         cmp.b    #'-',d1
  1373.         beq.s    22$
  1374.  
  1375.     ;------    Check for numeric.
  1376.         moveq    #ERR_BADVAL,d7
  1377.         cmp.b    #'0',d1
  1378.         blo.s    ParseError
  1379.         cmp.b    #'9',d1
  1380.         bhi.s    ParseError
  1381.  
  1382.     ;------    Accumulate numeric digit.  Overflow not tested.
  1383.         mulu    #10,d0
  1384.         sub.b    #'0',d1
  1385.         add.w    d1,d0
  1386.         bra.s    numloop
  1387.  
  1388.     ;------    Flip sense of minus sign.  We don't check for multiple
  1389.     ;------    instances.
  1390. 22$        not.b    d2
  1391.         bra.s    numloop
  1392.  
  1393.     ;------    Whitespace encountered; return to parser for storage.
  1394. 11$        tst.b    d2        ; This number negative?
  1395.         beq.s    110$
  1396.         neg.w    d0        ; Yep, turn it over
  1397. 110$
  1398.         subq.w    #1,a0        ; Push back char that stopped us
  1399.         rts
  1400.  
  1401.  
  1402. ****************
  1403. * Short routine to report parsing errors
  1404. *
  1405. ParseError    move.l    ErrStrs(pc,d7.w),d0    ; Pointer to error string.
  1406.         bra.s    UnWind
  1407.  
  1408.  
  1409. ErrStrs        dc.l    SyntaxErr,BadVal,ModeMissing,MissingVal
  1410.         dc.l    ExtraVal,HelpStr
  1411.  
  1412. ERR_SYNTAX    EQU    0
  1413. ERR_BADVAL    EQU    4
  1414. ERR_NOMODE    EQU    8
  1415. ERR_MISSINGVAL    EQU    12
  1416. ERR_EXTRAVAL    EQU    16
  1417. ERR_HELP    EQU    20
  1418.  
  1419.  
  1420. ****************************************************************************
  1421. * Parse Workbench icons.
  1422. *
  1423. * This routine scans all icons in the sm_ArgList.  Drawer icons are skipped.
  1424. * For each icon, each ToolType string is handed to the parser in turn.  If
  1425. * any error is reported, the whole thing aborts and the program won't start
  1426. * (maybe I should throw up a requester someday, eh?)
  1427. *
  1428. ParseWBArgs    movem.l    d2/d3/d7/a2-a5,-(sp)
  1429.         moveq    #0,d7        ; Clear error
  1430.  
  1431.     ;------    Open icon.library.
  1432.         lea    IconName(pc),a1
  1433.         moveq    #0,d0
  1434.         jsrlib    OpenLibrary
  1435.         tst.l    d0
  1436.         beq.s    err_noicon
  1437.         move.l    d0,a6
  1438.         move.l    DOSBase(pc),a5
  1439.  
  1440.     ;------    Get WBArg fields.
  1441.         move.l    WBStartMsg(pc),a2
  1442.         move.l    sm_NumArgs(a2),d2
  1443.         move.l    sm_ArgList(a2),a2
  1444.  
  1445.     ;------    Process each WBArg in turn.
  1446. ArgLoop        move.l    wa_Name(a2),a3
  1447.         tst.b    (a3)
  1448.         beq.s    NextArg        ; It's a directory icon, skip it
  1449.  
  1450.     ;------    CurrentDir() over to icon.
  1451.         move.l    wa_Lock(a2),d1
  1452.         exg    a5,a6        ; Get DOSBase
  1453.         jsrlib    CurrentDir
  1454.         exg    a5,a6        ; Recover IconBase
  1455.         move.l    d0,d3        ; Olddir
  1456.  
  1457.     ;------    Tell me about the icon.
  1458.         move.l    a3,a0        ; wa_Name
  1459.         jsrlib    GetDiskObject
  1460.         tst.l    d0
  1461.         beq.s    badob        ; Failed; ignore it
  1462.  
  1463.     ;------    Does this icon have any ToolType strings?
  1464.         move.l    d0,a3
  1465.         move.l    do_ToolTypes(a3),d0
  1466.         beq.s    EndStrs        ; No ToolType strings, skip it
  1467.         move.l    d0,a4
  1468.  
  1469.     ;------    Parse each ToolType string in turn.
  1470. ToolTypeLoop    move.l    (a4)+,d0
  1471.         beq.s    EndStrs        ; No more strings for this icon
  1472.  
  1473.         move.l    d0,a0        ; String
  1474.         bsr    ParseArgs
  1475.         move.l    d0,d7        ; Save error
  1476.         beq.s    ToolTypeLoop    ; No error; keep working
  1477.  
  1478.     ;------    Drop icon.
  1479. EndStrs        move.l    a3,a0
  1480.         jsrlib    FreeDiskObject
  1481.  
  1482.     ;------    Return to original location.
  1483. badob        move.l    d3,d1
  1484.         exg    a5,a6        ; DOSBase
  1485.         jsrlib    CurrentDir    ; Return to original directory
  1486.         exg    a5,a6        ; IconBase
  1487.  
  1488.         tst.l    d7        ; Was there a parsing error?
  1489.         bne.s    err_badwbparse    ; Yes, abort arg processing
  1490.  
  1491.     ;------    Advance to next WBArg
  1492. NextArg        addq.w    #wa_SIZEOF,a2    ; Advance WBArg
  1493.         subq.w    #1,d2        ; wb_NumArgs--
  1494.         bne.s    ArgLoop
  1495.  
  1496.     ;------    Close icon.library.
  1497. err_badwbparse    move.l    a6,a1
  1498.         move.l    (4).w,a6
  1499.         jsrlib    CloseLibrary
  1500.  
  1501. err_noicon    move.l    d7,d0
  1502.         movem.l    (sp)+,d2/d3/d7/a2-a5
  1503.         rts
  1504.  
  1505.  
  1506. ****************************************************************************
  1507. * Print string to CLI.  Pointer to string in D0.
  1508. *
  1509. PrintCLIStr    movem.l    d2/d3/a2/a6,-(sp)
  1510.         move.l    d0,a2        ; Save string pointer.
  1511.         move.l    DOSBase(pc),a6
  1512.         jsrlib    Output        ; Somewhere to print?
  1513.         move.l    d0,d1
  1514.         beq.s    99$        ; No, forget it
  1515.  
  1516.         move.l    a2,d2        ; Compute string length
  1517. 0$        tst.b    (a2)+
  1518.         bne.s    0$
  1519.         suba.l    d2,a2
  1520.         move.l    a2,d3
  1521.         subq.l    #1,d3
  1522.         jsrlib    Write        ; Write string
  1523. 99$
  1524.         movem.l    (sp)+,d2/d3/a2/a6
  1525.         rts
  1526.  
  1527.  
  1528. ****************************************************************************
  1529. * Bottom-of-frame interrupt routine.
  1530. *
  1531. BOFintr        moveq    #0,d0
  1532.         bset.l    #SIGBREAKB_CTRL_F,d0    ; F stands for Frame
  1533.         move.l    (4).w,a6
  1534.         jsrlib    Signal            ; Task ptr already in A1
  1535.  
  1536.         moveq    #0,d0
  1537.         rts
  1538.  
  1539.  
  1540. ****************************************************************************
  1541. * Set up the screen Y offset table.
  1542. *
  1543. GenYOffs    move.w    d2,-(sp)
  1544.  
  1545.         move.l    scrptr(pc),a0
  1546.         move.l    sc_ViewPort+vp_RasInfo(a0),a0
  1547.         move.l    ri_BitMap(a0),a0
  1548.         move.w    bm_BytesPerRow(a0),d1
  1549.         move.w    bm_Rows(a0),d2
  1550.  
  1551.         move.l    YOffTable(pc),a0
  1552.         moveq    #0,d0
  1553.         subq.w    #1,d2        ; Fencepost for DBRA
  1554.  
  1555. 1$        move.w    d0,(a0)+    ; Write offset
  1556.         add.w    d1,d0        ; Increment to next row
  1557.         dbra    d2,1$
  1558.  
  1559.         move.w    (sp)+,d2
  1560.         rts
  1561.  
  1562.  
  1563. ****************************************************************************
  1564. * Something I added to make things more reliable.
  1565. *
  1566. ClearBSS    move.l    #EndBSS,d2
  1567.         lea    StartBSS,a2
  1568.         sub.l    a2,d2
  1569.         subq.w    #1,d2
  1570. 1$        clr.b    (a2)+
  1571.         dbra    d2,1$
  1572.  
  1573.         rts
  1574.  
  1575.  
  1576. ****************************************************************************
  1577. * Data!  (Yes, Captain?)
  1578. *
  1579. delta_x        dc.w    0    ; Star movement
  1580. delta_y        dc.w    0
  1581. delta_z        dc.w    4
  1582. theta_x        dc.w    0    ; Initial/current rotation angles
  1583. theta_y        dc.w    0
  1584. theta_z        dc.w    0
  1585. spin_x        dc.w    0    ; Spin velocities
  1586. spin_y        dc.w    0
  1587. spin_z        dc.w    0
  1588.  
  1589. wrk_delta    dc.w    0,0,0    ; Working areas for the parser
  1590. wrk_theta    dc.w    0,0,0
  1591. wrk_spin    dc.w    0,0,0
  1592.  
  1593. CurrentSinCos    dc.w    0    ; theta_x
  1594.         dc.w    0
  1595.         dc.w    0    ; theta_y
  1596.         dc.w    0
  1597.         dc.w    0    ; theta_z
  1598.         dc.w    0
  1599. Matrix        dc.w    0,0,0,0,0,0,0,0,0
  1600. CenterX        dc.w    0
  1601. CenterY        dc.w    0
  1602. IBase        dc.l    0
  1603. GBase        dc.l    0
  1604. DOSBase        dc.l    0
  1605. winptr        dc.l    0
  1606. Plane1ptr    dc.l    0
  1607. Plane2ptr    dc.l    0
  1608. sprdat        dc.l    0
  1609. YOffTable    dc.l    0
  1610. WBStartMsg    dc.l    0
  1611. StarMsg        dc.l    0
  1612. StarSigMask    dc.l    0
  1613. StarSigs    dc.l    0
  1614. BackServ    dc.w    0
  1615.  
  1616. XCoords        dc.w    $FF37,$FED2,$6A,$FFF7,$C8,$CD,$FFF9,$132,$FF35
  1617.         dc.w    $FF9A,$FF7F,$16B,$EC,$FFF7,$186,$FF5A,$FF0D,$177
  1618.         dc.w    $FEAF,$6F,$FF5F,$FF22,$150,$2B,$FED5,$FEE3,$90,$AA
  1619.         dc.w    $FEBE,$13A,$12D,$FFA4,$FF49,$FEEE,$41,$164,$FF09
  1620.         dc.w    $8A,$FFE3,$D2,$FEBE,$13A,$12D,$FFA4,$FF49,$FEEE,$41
  1621.         dc.w    $164,$FF09,$8A,$FF46,$FF85,$154,$FF19,$60,$FF5C,$9B
  1622.         dc.w    $FFA8,$FF18,$158,$AE,$FF2F,$FE72,$21,$8C,$FE8B,$CF
  1623.         dc.w    $48,$FF7A,$137,$C8,$FED4
  1624. YCoords        dc.w    $FF5F,$FF22,$150,$2B,$FED5,$FEE3,$90,$AA,$FEBE,$13A
  1625.         dc.w    $12D,$FFA4,$FF49,$FEEE,$41,$164,$FF09,$8A,$FFE3,$D2
  1626.         dc.w    $FF37,$FED2,$6A,$FFF7,$C8,$CD,$FFF9,$132,$FF35
  1627.         dc.w    $FF9A,$FF7F,$16B,$EC,$FFF7,$186,$FF5A,$FF0D,$177
  1628.         dc.w    $FEAF,$6F,$177,$FEAF,$6F,$FF5F,$FF22,$150,$2B,$FED5
  1629.         dc.w    $FEE3,$90,$164,$FF09,$8A,$FFE3,$FF52,$FF2F,$18E,$21
  1630.         dc.w    $FF74,$FE8B,$CF,$FFB8,$86,$FEC9,$D2,$FF22,$94,$14D
  1631.         dc.w    $FE9B,$F4,$C8,$12C
  1632. ZCoords        dc.w    $FF52,$FF2F,$FE72,$21,$8C,$175,$FF31,$FFB8,$FF7A
  1633.         dc.w    $137,11,$153,$FF22,$94,$14D,$FE9B,$F4,$FEEC,$9B
  1634.         dc.w    $FF46,$FF85,$154,$FF19,$60,$FF5C,$9B,$FFA8,$FF18
  1635.         dc.w    $158,$FF61,$FE8F,$F8,$FEE7,$8C,$FF85,$48,$FEAC
  1636.         dc.w    $FF17,$6A,$13B,$FF01,$FF3A,$FFF9,7,$BE,$12B,$FED1
  1637.         dc.w    $FE94,$FC,$FF91,$CD,$FFF9,$132,$FF35,$FF9A,$FF7F
  1638.         dc.w    $16B,$EC,$FFF7,$186,$FED2,$6A,$FFF7,$C8,$CD,$FFF9
  1639.         dc.w    $132,$FF35,$FF9A,$FF7F,$96,$FF06
  1640.  
  1641.  
  1642. SineTable    dc.w    0,50,101,151,201,251,302,352
  1643.         dc.w    402,452,503,553,603,653,704,754
  1644.         dc.w    804,854,904,955,1005,1055,1105,1155
  1645.         dc.w    1205,1255,1306,1356,1406,1456,1506,1556
  1646.         dc.w    1606,1656,1706,1756,1806,1856,1906,1956
  1647.         dc.w    2006,2055,2105,2155,2205,2255,2305,2354
  1648.         dc.w    2404,2454,2503,2553,2603,2652,2702,2752
  1649.         dc.w    2801,2851,2900,2949,2999,3048,3098,3147
  1650.         dc.w    3196,3246,3295,3344,3393,3442,3492,3541
  1651.         dc.w    3590,3639,3688,3737,3786,3835,3883,3932
  1652.         dc.w    3981,4030,4078,4127,4176,4224,4273,4321
  1653.         dc.w    4370,4418,4467,4515,4563,4612,4660,4708
  1654.         dc.w    4756,4804,4852,4900,4948,4996,5044,5092
  1655.         dc.w    5139,5187,5235,5282,5330,5377,5425,5472
  1656.         dc.w    5520,5567,5614,5661,5708,5756,5803,5850
  1657.         dc.w    5897,5943,5990,6037,6084,6130,6177,6223
  1658.         dc.w    6270,6316,6363,6409,6455,6501,6547,6593
  1659.         dc.w    6639,6685,6731,6777,6823,6868,6914,6960
  1660.         dc.w    7005,7050,7096,7141,7186,7231,7276,7321
  1661.         dc.w    7366,7411,7456,7501,7545,7590,7635,7679
  1662.         dc.w    7723,7768,7812,7856,7900,7944,7988,8032
  1663.         dc.w    8076,8119,8163,8207,8250,8293,8337,8380
  1664.         dc.w    8423,8466,8509,8552,8595,8638,8680,8723
  1665.         dc.w    8765,8808,8850,8892,8935,8977,9019,9061
  1666.         dc.w    9102,9144,9186,9227,9269,9310,9352,9393
  1667.         dc.w    9434,9475,9516,9557,9598,9638,9679,9720
  1668.         dc.w    9760,9800,9841,9881,9921,9961,10001,10040
  1669.         dc.w    10080,10120,10159,10198,10238,10277,10316,10355
  1670.         dc.w    10394,10433,10471,10510,10549,10587,10625,10663
  1671.         dc.w    10702,10740,10778,10815,10853,10891,10928,10966
  1672.         dc.w    11003,11040,11077,11114,11151,11188,11224,11261
  1673.         dc.w    11297,11334,11370,11406,11442,11478,11514,11550
  1674.         dc.w    11585,11621,11656,11691,11727,11762,11797,11831
  1675.         dc.w    11866,11901,11935,11970,12004,12038,12072,12106
  1676.         dc.w    12140,12173,12207,12240,12274,12307,12340,12373
  1677.         dc.w    12406,12439,12472,12504,12537,12569,12601,12633
  1678.         dc.w    12665,12697,12729,12760,12792,12823,12854,12885
  1679.         dc.w    12916,12947,12978,13008,13039,13069,13100,13130
  1680.         dc.w    13160,13190,13219,13249,13279,13308,13337,13366
  1681.         dc.w    13395,13424,13453,13482,13510,13538,13567,13595
  1682.         dc.w    13623,13651,13678,13706,13733,13761,13788,13815
  1683.         dc.w    13842,13869,13896,13922,13949,13975,14001,14027
  1684.         dc.w    14053,14079,14104,14130,14155,14181,14206,14231
  1685.         dc.w    14256,14280,14305,14329,14354,14378,14402,14426
  1686.         dc.w    14449,14473,14497,14520,14543,14566,14589,14612
  1687.         dc.w    14635,14657,14680,14702,14724,14746,14768,14789
  1688.         dc.w    14811,14832,14854,14875,14896,14917,14937,14958
  1689.         dc.w    14978,14999,15019,15039,15059,15078,15098,15118
  1690.         dc.w    15137,15156,15175,15194,15213,15231,15250,15268
  1691.         dc.w    15286,15304,15322,15340,15357,15375,15392,15409
  1692.         dc.w    15426,15443,15460,15476,15493,15509,15525,15541
  1693.         dc.w    15557,15573,15588,15604,15619,15634,15649,15664
  1694.         dc.w    15679,15693,15707,15722,15736,15750,15763,15777
  1695.         dc.w    15791,15804,15817,15830,15843,15856,15868,15881
  1696.         dc.w    15893,15905,15917,15929,15941,15952,15964,15975
  1697.         dc.w    15986,15997,16008,16018,16029,16039,16049,16059
  1698.         dc.w    16069,16079,16088,16098,16107,16116,16125,16134
  1699.         dc.w    16143,16151,16160,16168,16176,16184,16192,16199
  1700.         dc.w    16207,16214,16221,16228,16235,16242,16248,16255
  1701.         dc.w    16261,16267,16273,16279,16284,16290,16295,16300
  1702.         dc.w    16305,16310,16315,16319,16324,16328,16332,16336
  1703.         dc.w    16340,16343,16347,16350,16353,16356,16359,16362
  1704.         dc.w    16364,16367,16369,16371,16373,16375,16376,16378
  1705.         dc.w    16379,16380,16381,16382,16383,16383,16384,16384
  1706.         dc.w    16384
  1707.  
  1708. colors        dc.w    0,$336,$669,$CCF
  1709.  
  1710. GfxName        dc.b    'graphics.library',0
  1711. IntuiName    dc.b    'intuition.library',0
  1712. DOSName        dc.b    'dos.library',0
  1713. IconName    dc.b    'icon.library',0
  1714. ESName        dc.b    'EuroStars',0
  1715. ESPortName    dc.b    'EUROSTARS',0    ; ARexx wants uppercase.  Sigh...
  1716.  
  1717.  
  1718. ****************
  1719. * Error strings
  1720. *
  1721. SyntaxErr    dc.b    "Syntax error.",10,0
  1722. BadVal        dc.b    "Bad value.",10,0
  1723. ModeMissing    dc.b    "Must specify M, R, or S before XYZ.",10,0
  1724. MissingVal    dc.b    "Expecting more values.",10,0
  1725. ExtraVal    dc.b    "Unexpected extra value.",10,0
  1726.         dc.b    "$VER: "
  1727. HelpStr        dc.b    "ES 2.0 (18.10.92) -- EuroStars",10
  1728.         dc.b    "Written by Leo L. Schwab.",10,10
  1729.         dc.b    "Usage:",10
  1730.         dc.b    9,"ES [MRS][XYZ] <value> [<value> ... ]",10
  1731.         dc.b    9,"ES B",9,"; Run as background server",10
  1732.         dc.b    9,"ES Q",9,"; Quit (ARexx only)",10,10
  1733.         dc.b    "ARexx port name is EUROSTARS.",10,0
  1734.  
  1735.  
  1736. ****************
  1737. * Static structure definitions.
  1738. *
  1739.         cnop    0,4
  1740.  
  1741.     ;------    NewScreen
  1742. scr_def        dc.w    0,0
  1743. scrwide        dc.w    352
  1744. scrhigh        dc.w    230
  1745.         dc.w    2
  1746.         dc.b    0,1
  1747.         dc.w    0
  1748.         dc.w    CUSTOMSCREEN!SCREENQUIET
  1749.         dc.l    0
  1750.         dc.l    ESName
  1751.         dc.l    0
  1752.         dc.l    0
  1753.  
  1754.     ;------    NewWindow
  1755. windef        dc.w    0,0
  1756.         dc.w    352,230
  1757.         dc.b    -1,-1
  1758.         dc.l    MOUSEBUTTONS
  1759.         dc.l    SMART_REFRESH!BACKDROP!BORDERLESS!ACTIVATE!RMBTRAP
  1760.         dc.l    0
  1761.         dc.l    0
  1762.         dc.l    0
  1763. scrptr        dc.l    0
  1764.         dc.l    0
  1765.         dc.w    0,0,0,0
  1766.         dc.w    CUSTOMSCREEN
  1767.  
  1768.     ;------    MessagePort
  1769. rexxport    dc.l    0,0        ; LN_SUCC, LN_PRED
  1770.         dc.b    NT_MSGPORT    ; LN_TYPE
  1771.         dc.b    0        ; LN_PRI
  1772.         dc.l    ESPortName    ; LN_NAME
  1773.         dc.b    PA_SIGNAL    ; MP_FLAGS
  1774. mpsigbit    dc.b    -1        ; MP_SIGBIT
  1775. mpsigtask    dc.l    0        ; MP_SIGTASK
  1776.         ds.b    LH_SIZE        ; MP_MSGLIST,LH_SIZE
  1777.  
  1778.     ;------    Startup Message
  1779. startmsg    dc.l    0,0        ; LN_SUCC, LN_PRED
  1780.         dc.b    NT_MESSAGE    ; LN_TYPE
  1781.         dc.b    0        ; LN_PRI
  1782.         dc.l    ESName        ; LN_NAME
  1783.         dc.l    rexxport    ; MN_REPLYPORT
  1784.         dc.w    MN_SIZE        ; MN_LENGTH
  1785.  
  1786.     ;------    Interrupt structure
  1787. BOFintrnode    dc.l    0,0        ; LN_SUCC, LN_PRED
  1788.         dc.b    NT_INTERRUPT    ; LN_TYPE
  1789.         dc.b    0        ; LN_PRI
  1790.         dc.l    ESName        ; LN_NAME
  1791. StarTask    dc.l    0        ; IS_DATA
  1792.         dc.l    BOFintr        ; IS_CODE
  1793.  
  1794.  
  1795. ****************************************************************************
  1796. * Uninitialized data
  1797. *
  1798.         SECTION EuroStars,BSS
  1799. StartBSS:
  1800.  
  1801. MyCopList    ds.b    ucl_SIZEOF
  1802. TransformBuff    ds.w    NSTARS*3    ; Written in YXZ order
  1803. PlaneOffsets    ds.w    NSTARS
  1804.  
  1805. EndBSS:
  1806.         END
  1807.